package com.easygoods.service;

import com.bestvike.stone.core.lang.BeanUtils;
import com.bestvike.stone.core.lang.RandomUtils;
import com.bestvike.stone.core.lang.StringUtils;
import com.bestvike.stone.spring.exception.BusinessException;
import com.bestvike.stone.spring.exception.ErrorCode;
import com.bestvike.stone.spring.page.PageableRequest;
import com.bestvike.stone.spring.page.PageableResponse;
import com.bestvike.stone.spring.service.BaseService;
import com.easygoods.dao.GoodsSpuDao;
import com.easygoods.dao.StoreInfoDao;
import com.easygoods.dao.StoreSpuDao;
import com.easygoods.entity.MemberInfo;
import com.easygoods.entity.StoreInfo;
import com.easygoods.entity.StoreSpu;
import com.easygoods.entityex.GoodsSpuEx;
import com.easygoods.entityex.GoodsSpuWithEarnRate;
import com.easygoods.request.StarSpuRequest;
import com.easygoods.response.SpuListEarnRateResponse;
import com.easygoods.response.SpuListResponse;
import com.easygoods.response.StarSpuResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;
import tk.mybatis.mapper.entity.Example;

import java.math.BigDecimal;
import java.text.NumberFormat;
import java.util.List;

/**
 * Created by 许崇雷 on 2019-01-08.
 */
@Service
public class StoreService extends BaseService {
    @Autowired
    private MemberService memberService;
    @Autowired
    private StoreSpuDao storeSpuDao;
    @Autowired
    private StoreInfoDao storeInfoDao;
    @Autowired
    private GoodsSpuDao goodsSpuDao;
    @Autowired
    private GoodsService goodsService;

    //收藏
    @SuppressWarnings("Duplicates")
    public StarSpuResponse starSpu(StarSpuRequest request) {
        StoreInfo storeInfo = this.memberService.getStoreInfo();
        if (storeInfo == null)
            throw new BusinessException(ErrorCode.ERROR_SERVER, "该用户没有对应的 store");
        String storeId = storeInfo.getId();
        if (StringUtils.isBlank(storeId))
            throw new BusinessException(ErrorCode.ERROR_SERVER, "该用户没有对应的 storeId");
        StarSpuResponse starSpuResponse = new StarSpuResponse();
        boolean isFirstStar = !this.storeSpuDao.isStoreSpuExist(storeId);
        starSpuResponse.setIsFirstStar(isFirstStar);
        Example example = new Example(StoreSpu.class);
        example.createCriteria().andEqualTo(StoreSpu.STORE_ID, storeId).andEqualTo(StoreSpu.SPU_ID, request.getSpuId());
        StoreSpu storeSpuExists = this.storeSpuDao.selectOneByExample(example);
        if (storeSpuExists != null) {
            return starSpuResponse;
        }

        StoreSpu storeSpu = new StoreSpu();
        storeSpu.setId(RandomUtils.randomUUID());
        storeSpu.setStoreId(storeId);
        storeSpu.setSpuId(request.getSpuId());
        storeSpu.beforeInsert();
        this.storeSpuDao.insert(storeSpu);
        return starSpuResponse;
    }

    //取消收藏
    @SuppressWarnings("Duplicates")
    public void unStarSpu(StarSpuRequest request) {
        StoreInfo storeInfo = this.memberService.getStoreInfo();
        if (storeInfo == null)
            throw new BusinessException(ErrorCode.ERROR_SERVER, "该用户没有对应的 store");
        String storeId = storeInfo.getId();
        if (StringUtils.isBlank(storeId))
            throw new BusinessException(ErrorCode.ERROR_SERVER, "该用户没有对应的 storeId");

        Example example = new Example(StoreSpu.class);
        example.createCriteria().andEqualTo(StoreSpu.STORE_ID, storeId)
                .andEqualTo(StoreSpu.SPU_ID, request.getSpuId());
        this.storeSpuDao.deleteByExample(example);
    }

    //判断当前用户是否收藏了指定 spuId
    public boolean isStar(String spuId) {
        Assert.hasText(spuId, "spuId can not be empty");

        StoreInfo storeInfo = this.memberService.getStoreInfo();
        if (storeInfo == null) {
            this.log.warn("该用户不存在store信息");
            throw new BusinessException(ErrorCode.ERROR_SERVER, "无效的用户");
        }
        StoreSpu storeSpu = new StoreSpu();
        storeSpu.setStoreId(storeInfo.getId());
        storeSpu.setSpuId(spuId);

        final Example example = new Example(StoreSpu.class);
        example.createCriteria().andEqualTo(StoreSpu.STORE_ID, storeInfo.getId())
                .andEqualTo(StoreSpu.SPU_ID, spuId);
        return this.storeSpuDao.selectOneByExample(example) != null;
    }

    //增加购买统计,buyNum,buyAmount 可以为负数
    public void increaseBuyInfo(String memberId, int buyNum, BigDecimal buyOriginAmt, BigDecimal buyMemberAmt, BigDecimal buyPayAmt) {
        Assert.hasText(memberId, "memberId can not be empty");
        Assert.notNull(buyOriginAmt, "buyOriginAmt can not be null");
        Assert.notNull(buyMemberAmt, "buyMemberAmt can not be null");
        Assert.notNull(buyPayAmt, "buyPayAmt can not be null");

        int count = this.storeInfoDao.increaseStoreBuy(memberId, buyNum, buyOriginAmt, buyMemberAmt, buyPayAmt);
        if (count != 1) {
            this.log.warn("更新购买信息失败 memberId:" + memberId);
            throw new BusinessException(ErrorCode.ERROR_SERVER, "操作失败,请重试");
        }
    }

    //获取用户收藏的spu
    public PageableResponse<SpuListResponse> getStoreSpuList(PageableRequest pageableRequest) {
        StoreInfo storeInfo = this.memberService.getStoreInfo();
        List<GoodsSpuEx> goodsSpuExList = this.goodsSpuDao.getSpuListByStoreId(storeInfo.getId(), pageableRequest.toRowBounds());
        final List<SpuListResponse> goodsSpuListResponse = BeanUtils.toList(goodsSpuExList, SpuListResponse.class);
        return PageableResponse.create(goodsSpuExList, goodsSpuListResponse);
    }

    //计算收藏商品的当前等级等级以及下一等级的会员价，可赚金额、收益率
    private void computeEarnRate(List<GoodsSpuWithEarnRate> spuList, int grade) {
        final NumberFormat percentInstance = NumberFormat.getPercentInstance();
        percentInstance.setMaximumFractionDigits(2);
        for (GoodsSpuWithEarnRate spu : spuList) {
            //计算当前等级会员价,可赚，收益率
            BigDecimal originPrice = spu.getOriginPrice();
            BigDecimal minPrice = spu.getMinPrice();
            spu.setMemberPrice(this.goodsService.getMemberPrice(grade, minPrice, originPrice));
            spu.setEarnRate(this.goodsService.getEarnRate(originPrice, spu.getMemberPrice()));
            spu.setEarnRateText(percentInstance.format(spu.getEarnRate()));
            //计算下一等级会员价，可赚，收益率
            BigDecimal nextMemberPrice = this.goodsService.getMemberPrice(grade + 1, minPrice, originPrice);
            spu.setNextEarnRate(this.goodsService.getEarnRate(originPrice, nextMemberPrice));
            spu.setNextEarnRateText(percentInstance.format(spu.getNextEarnRate()));
        }
    }

    //在收藏的商品中查询收益率最高的两种商品
    public List<SpuListEarnRateResponse> getStoreSpuListWithEarnRate() {
        StoreInfo storeInfo = this.memberService.getStoreInfo();
        MemberInfo memberInfo = this.memberService.getMemberInfo();

        List<GoodsSpuWithEarnRate> spuList = this.storeSpuDao.findTopEarnRateSpuList(storeInfo.getId());
        this.computeEarnRate(spuList, memberInfo.getGrade());
        return BeanUtils.toList(spuList, SpuListEarnRateResponse.class);
    }
}
